﻿namespace CatClient.Configuration
{
    using CatClient.Util;
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Runtime.CompilerServices;
    using System.Web.Script.Serialization;

    internal static class CatConfigManager
    {
        private static HashSet<string> s_CatKeys = new HashSet<string>();
        private static Dictionary<string, string> m_configinfo = new Dictionary<string, string>();   

        static CatConfigManager()
        {
            s_CatKeys.Add("CatEnable");
            s_CatKeys.Add("CatServer");
            s_CatKeys.Add("CatDomain");
            s_CatKeys.Add("CatHeartbeatEnabled");
            s_CatKeys.Add("RegistryServiceDomain");
            s_CatKeys.Add("CatExTryInterval");
            s_CatKeys.Add("CatExCheckDuration");
            s_CatKeys.Add("CatExFuseThreshold");
            s_CatKeys.Add("CatConCheckDuration");
            s_CatKeys.Add("CatConFuseThreshold");
            s_CatKeys.Add("MsgMaxSize");
            s_CatKeys.Add("CatQueueSize");
            s_CatKeys.Add("CatNullMsgLog");
            s_CatKeys.Add("CurrentKeyCheck");
            s_CatKeys.Add("DefaultLogCount");
        }

        public static bool ContainsKey(string key) =>
            m_configinfo.ContainsKey(key);

        public static T ConvertToObject<T>(this string value, Type type)
        {
            if (type == typeof(string))
            {
                return (T)((object)value);
            }
            if (type == typeof(short))
            {
                return (T)((object)Convert.ToInt16(value));
            }
            if (type == typeof(int))
            {
                return (T)((object)Convert.ToInt32(value));
            }
            if (type == typeof(long))
            {
                return (T)((object)Convert.ToInt64(value));
            }
            if (type == typeof(ushort))
            {
                return (T)((object)Convert.ToUInt16(value));
            }
            if (type == typeof(uint))
            {
                return (T)((object)Convert.ToUInt32(value));
            }
            if (type == typeof(ulong))
            {
                return (T)((object)Convert.ToUInt64(value));
            }
            if (type == typeof(float))
            {
                return (T)((object)Convert.ToSingle(value));
            }
            if (type == typeof(double))
            {
                return (T)((object)Convert.ToDouble(value));
            }
            if (type == typeof(DateTime))
            {
                return (T)((object)Convert.ToDateTime(value));
            }
            if (type == typeof(byte))
            {
                return (T)((object)Convert.ToByte(value));
            }
            if (type == typeof(bool))
            {
                return (T)((object)Convert.ToBoolean(value));
            }
            if (type == typeof(char))
            {
                return (T)((object)Convert.ToChar(value));
            }
            if (type == typeof(decimal))
            {
                return (T)((object)Convert.ToDecimal(value));
            }
            if (type == typeof(object))
            {
                return (T)((object)value);
            }
            if (type.IsEnum)
            {
                try
                {
                    return (T)((object)Enum.Parse(type, value, true));
                }
                catch
                {
                }
            }
            return JsonConvert.DeserializeObject<T>(value);
        }

        public static T GetConfigObject<T>(string key)
        {
            string configValue = GetConfigValue(key);
            if (string.IsNullOrEmpty(configValue))
            {
                return default(T);
            }
            Type type = typeof(T);
            return configValue.ConvertToObject<T>(type);
        }

        public static T GetConfigObject<T>(string key, T defaultValue)
        {
            string configValue = GetConfigValue(key);
            if (string.IsNullOrEmpty(configValue))
            {
                if (defaultValue != null)
                {
                    return defaultValue;
                }
                return default(T);
            }
            Type type = typeof(T);
            return configValue.ConvertToObject<T>(type);
        }

        public static string GetConfigValue(string key)
        {
            if (m_configinfo.ContainsKey(key))
            {
                string localconfigs = ConfigurationManager.AppSettings["LocalConfigList"];
                if (!string.IsNullOrEmpty(localconfigs))
                {
                    char[] separator = new char[] { '|' };
                    if (localconfigs.Split(separator).Contains<string>(key))
                        return ConfigurationManager.AppSettings[key];
                }
                return m_configinfo[key];
            }

            if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings[key]))
                return ConfigurationManager.AppSettings[key];
            
            return string.Empty;
        }

        public static string GetConfigValue(string key, string defaultValue)
        {
            string configValue = GetConfigValue(key);
            if (!string.IsNullOrEmpty(configValue))
            {
                return configValue;
            }
            return defaultValue;
        }
    }
}

